package main

import (
	"errors"
	"fmt"
	"github.com/golang-jwt/jwt/v5"
	"time"
)

var mySigningKey = []byte("aide")

type MyCustomClaims struct {
	Foo string `json:"foo"`
	jwt.RegisteredClaims
}

func main() {
	claims := MyCustomClaims{
		"bar",
		jwt.RegisteredClaims{
			//exp（Expiration Time）：过期时间，表示该JWT的有效期，必须在该时间之前验证。
			//ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Second)),
			ExpiresAt: jwt.NewNumericDate(time.Unix(1688024295, 0)),
			//iat（Issued At）：签发时间，表示该JWT的签发时间。
			IssuedAt: jwt.NewNumericDate(time.Now()),
			//nbf（Not Before）：生效时间，表示该JWT在此时间之前是无效的。
			NotBefore: jwt.NewNumericDate(time.Now()),
			//iss（Issuer）：发行人，表示该JWT的签发者。
			Issuer: "test",
			//sub（Subject）：主题，表示该JWT所面向的用户。
			Subject: "somebody",
			//jti（JWT ID）：JWT的唯一标识符，用于防止重放攻击。
			ID: "1",
			//aud（Audience）：观众，表示该JWT的接收者。
			Audience: []string{"somebody_else"},
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// Sign and get the complete encoded token as a string using the secret
	tokenString, err := token.SignedString(mySigningKey)

	fmt.Println(tokenString, err)

	parseToken(tokenString)

}

func parseToken(tokenString string) {
	token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return mySigningKey, nil
	})

	if token.Valid {
		if claims, ok := token.Claims.(*MyCustomClaims); ok {
			fmt.Printf("%v %v", claims.Foo, claims.RegisteredClaims.Issuer)
			fmt.Printf("%v", claims)
		}
		fmt.Println("You look nice today")
	} else if errors.Is(err, jwt.ErrTokenMalformed) {
		fmt.Println("That's not even a token")
	} else if errors.Is(err, jwt.ErrTokenSignatureInvalid) {
		// Invalid signature
		fmt.Println("Invalid signature")
	} else if errors.Is(err, jwt.ErrTokenExpired) || errors.Is(err, jwt.ErrTokenNotValidYet) {
		// Token is either expired or not active yet
		fmt.Println("Timing is everything")
	} else {
		fmt.Println("Couldn't handle this token:", err)
	}
}
